home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 September (Japanese) / CICA Shareware for Windows CD-ROM (Walnut Creek) (September 1995) (Japanese) (Disc 2).iso / disc2 / nt / source.exe / POSIX / CAT / CAT.C next >
Encoding:
C/C++ Source or Header  |  1993-06-23  |  9.2 KB  |  440 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Kevin Fall.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37.  
  38. #ifdef DF_POSIX
  39. #include <misc.h>
  40. #include <bsdlib.h>
  41. #endif
  42. #include <sys/cdefs.h>
  43.  
  44. #ifndef lint
  45. char copyright[] =
  46. "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
  47.  All rights reserved.\n";
  48. #endif /* not lint */
  49.  
  50. #ifndef lint
  51. static char sccsid[] = "@(#)cat.c    5.15 (Berkeley) 5/23/91";
  52. #endif /* not lint */
  53.  
  54. #ifdef _POSIX_SOURCE
  55. #else
  56. #include <sys/param.h>
  57. #endif
  58.  
  59. #include <sys/stat.h>
  60. #include <fcntl.h>
  61. #include <errno.h>
  62. #include <unistd.h>
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include <ctype.h>
  67.  
  68. int bflag, eflag, nflag, sflag, tflag, vflag;
  69. int rval;
  70. char *filename;
  71.  
  72. void cook_args __P((char **));
  73. void cook_buf __P((register FILE *));
  74. void raw_args __P((char **));
  75. void raw_cat __P((register int));
  76. void err __P((int, const char *, ...));
  77.  
  78. #if WIN_NT
  79. extern int globulate __P((int, int, char **));
  80. extern void deglobulate __P((void));
  81. extern int globulated_argc;
  82. extern char **globulated_argv;
  83. pid_t ppid;
  84. int globulation;
  85. #endif
  86.  
  87. int
  88. #if __STDC__
  89. main (int argc, char **argv)
  90. #else
  91. main(argc, argv)
  92.     int argc;
  93.     char **argv;
  94. #endif
  95. {
  96.     extern int optind;
  97.     int ch;
  98. #if 0
  99. ssize_t n;
  100. int saved_errno;
  101. static const char text[] = "moo goo gi pan";
  102. #endif
  103.  
  104. #if WIN_NT
  105.     ppid = getppid();
  106.     if (ppid == (pid_t) 1) /* if parent is CMD.EXE */
  107.     {
  108.         globulation = globulate(1, argc, argv);
  109.         if (globulation == 0)
  110.         {
  111.             argc = globulated_argc;
  112.             argv = globulated_argv;
  113.         }
  114.     }
  115. #endif
  116. #if 0
  117. n = write(1, text, sizeof text - 1);
  118. saved_errno = errno;
  119. fprintf(stderr, "n: %d; errno: %d\n", n, saved_errno);
  120. fflush(stderr);
  121. #endif
  122.     while ((ch = getopt(argc, argv, "benstuv")) != EOF)
  123.         switch (ch) {
  124.         case 'b':
  125.             bflag = nflag = 1;    /* -b implies -n */
  126.             break;
  127.         case 'e':
  128.             eflag = vflag = 1;    /* -e implies -v */
  129.             break;
  130.         case 'n':
  131.             nflag = 1;
  132.             break;
  133.         case 's':
  134.             sflag = 1;
  135.             break;
  136.         case 't':
  137.             tflag = vflag = 1;    /* -t implies -v */
  138.             break;
  139.         case 'u':
  140.             setbuf(stdout, (char *)NULL);
  141.             break;
  142.         case 'v':
  143.             vflag = 1;
  144.             break;
  145.         case '?':
  146.             (void)fprintf(stderr,
  147.                 "usage: cat [-benstuv] [-] [file ...]\n");
  148. #if WIN_NT
  149.             if (ppid == (pid_t) 1 && globulation == 0)
  150.                 deglobulate();
  151. #endif
  152.             exit(EXIT_FAILURE);
  153.         }
  154.     argv += optind;
  155.  
  156.     if (bflag || eflag || nflag || sflag || tflag || vflag)
  157.         cook_args(argv);
  158.     else
  159.         raw_args(argv);
  160. #ifdef DF_POSIX /* DF_MSS */
  161. #if WIN_NT
  162.     if (ppid == (pid_t) 1 && globulation == 0)
  163.         deglobulate();
  164. #endif
  165.     return rval;
  166. #else
  167.         if (ch = fclose(stdout)) {
  168.         fprintf(stdout, "ch X%dX\n", ch);
  169.         fflush(stdout);
  170.         err(EXIT_FAILURE, "stdout: %s", strerror(errno));
  171.     }
  172.     exit(rval);
  173. #endif
  174. }
  175.  
  176. void
  177. #if __STDC__
  178. cook_args (char **argv)
  179. #else
  180. cook_args(argv)
  181.     char **argv;
  182. #endif
  183. {
  184.     register FILE *fp;
  185.  
  186.     fp = stdin;
  187.     filename = "stdin";
  188.     do {
  189.         if (*argv) {
  190.             if (!strcmp(*argv, "-"))
  191.                 fp = stdin;
  192.             else if (!(fp = fopen(*argv, "r"))) {
  193. #if 0
  194. fprintf(stderr, "err #1\n");
  195. fflush(stderr);
  196. #endif
  197.                 err(0, "%s: %s", *argv, strerror(errno));
  198.                 ++argv;
  199.                 continue;
  200.             }
  201.             filename = *argv++;
  202.         }
  203.         cook_buf(fp);
  204.         if (fp != stdin)
  205.             (void)fclose(fp);
  206.     } while (*argv);
  207. }
  208.  
  209. void
  210. #if __STDC__
  211. cook_buf (register FILE *fp)
  212. #else
  213. cook_buf(fp)
  214.     register FILE *fp;
  215. #endif
  216. {
  217.     register int ch, gobble, line, prev;
  218. #if WIN_NT
  219.     register int c;
  220. #endif
  221.  
  222.     line = gobble = 0;
  223.     for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
  224. #if WIN_NT
  225.         if ( ch == '\r' ) 
  226.                     if (( c = getc(fp)) == '\n' )
  227.             {
  228.                 if ( !gobble )
  229.                     putchar(ch);
  230.                 ch = c;
  231.             }
  232.             else
  233.             {
  234.                 if ( c == EOF )
  235.                 {
  236.                     putchar(ch);
  237.                     break;
  238.                 }
  239.                 ungetc(c,fp);
  240.             }
  241. #endif
  242.         if (prev == '\n') {
  243.             if (ch == '\n') {
  244.                 if (sflag) {
  245.                     if (!gobble && putchar(ch) == EOF)
  246.                         break;
  247.                     gobble = 1;
  248.                     continue;
  249.                 }
  250.                 if (nflag && !bflag) {
  251.                     (void)fprintf(stdout, "%6d\t", ++line);
  252.                     if (ferror(stdout))
  253.                         break;
  254.                 }
  255.             } else if (nflag) {
  256.                 (void)fprintf(stdout, "%6d\t", ++line);
  257.                 if (ferror(stdout))
  258.                     break;
  259.             }
  260.         }
  261.         gobble = 0;
  262.         if (ch == '\n') {
  263.             if (eflag)
  264.                 if (putchar('$') == EOF)
  265.                     break;
  266.         } else if (ch == '\t') {
  267.             if (tflag) {
  268.                 if (putchar('^') == EOF || putchar('I') == EOF)
  269.                     break;
  270.                 continue;
  271.             }
  272.         } else if (vflag) {
  273.             if (!isascii(ch)) {
  274.                 if (putchar('M') == EOF || putchar('-') == EOF)
  275.                     break;
  276.                 ch = toascii(ch);
  277.             }
  278.             if (iscntrl(ch)) {
  279.                 if (putchar('^') == EOF ||
  280.                     putchar(ch == '\177' ? '?' :
  281.                     ch | 0100) == EOF)
  282.                     break;
  283.                 continue;
  284.             }
  285.         }
  286.         if (putchar(ch) == EOF)
  287.             break;
  288.     }
  289.     if (ferror(fp)) {
  290. #if 0
  291. fprintf(stderr, "err #2\n");
  292. fflush(stderr);
  293. #endif
  294.         err(0, "cat: %s", strerror(errno));
  295.         clearerr(fp);
  296.     }
  297.     if (ferror(stdout)) {
  298. #if 0
  299. fprintf(stderr, "err #3\n");
  300. fflush(stderr);
  301. #endif
  302.         err(EXIT_FAILURE, "stdout: %s", strerror(errno));
  303.     }
  304. }
  305.  
  306. void
  307. #if __STDC__
  308. raw_args (char **argv)
  309. #else
  310. raw_args(argv)
  311.     char **argv;
  312. #endif
  313. {
  314.     register int fd;
  315.  
  316.     fd = fileno(stdin);
  317.     filename = "stdin";
  318.     do {
  319.         if (*argv) {
  320.             if (!strcmp(*argv, "-"))
  321.                 fd = fileno(stdin);
  322.             else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
  323. #if 0
  324. fprintf(stderr, "err #4\n");
  325. fflush(stderr);
  326. #endif
  327.                 err(0, "%s: %s", *argv, strerror(errno));
  328.                 ++argv;
  329.                 continue;
  330.             }
  331.             filename = *argv++;
  332.         }
  333.         raw_cat(fd);
  334.         if (fd != fileno(stdin))
  335.             (void)close(fd);
  336.     } while (*argv);
  337. }
  338.  
  339. void
  340. #if __STDC__
  341. raw_cat (register int rfd)
  342. #else
  343. raw_cat(rfd)
  344.     register int rfd;
  345. #endif
  346. {
  347.     register int nr, nw, off, wfd;
  348.     static int bsize;
  349.     static char *buf;
  350.     struct stat sbuf;
  351.  
  352.     wfd = fileno(stdout);
  353.     if (!buf) {
  354.         if (fstat(wfd, &sbuf)) {
  355. #if 0
  356. fprintf(stderr, "err #5\n");
  357. fflush(stderr);
  358. #endif
  359.             err(EXIT_FAILURE, "%s: %s", filename, strerror(errno));
  360.         }
  361. #ifdef DF_POSIX  /* DF_MSS */
  362.         bsize = __max(/*sbuf.st_blksize*/ 1024, 1024);
  363. #else
  364.         bsize = MAX(sbuf.st_blksize, 1024);
  365. #endif
  366.  
  367.         if (!(buf = malloc((u_int)bsize))) {
  368. #if 0
  369. fprintf(stderr, "err #6\n");
  370. fflush(stderr);
  371. #endif
  372.             err(EXIT_FAILURE, "%s", strerror(errno));
  373.         }
  374.     }
  375.     while ((nr = read(rfd, buf, bsize)) > 0) {
  376. #if 0
  377. fprintf(stderr, "read %d bytes: \"%.*s\"\n", nr, nr, buf);
  378. fflush(stderr);
  379. #endif
  380.         for (off = 0; off < nr; nr -= nw, off += nw)
  381.             if ((nw = write(wfd, buf + off, nr)) < 0) {
  382. #if 0
  383. int saved_errno;
  384. saved_errno = errno;
  385. fprintf(stderr, "err #7 - errno: %d; wfd: %d; isatty(wfd): %d\n", saved_errno, wfd, isatty(wfd));
  386. fflush(stderr);
  387. #endif
  388.                 err(EXIT_FAILURE, "stdout");
  389.             }
  390.     }
  391.     if (nr < 0) {
  392. #if 0
  393. fprintf(stderr, "err #8\n");
  394. fflush(stderr);
  395. #endif
  396.         err(0, "%s: %s", filename, strerror(errno));
  397.     }
  398. }
  399.  
  400. #if __STDC__
  401. #include <stdarg.h>
  402. #else
  403. #include <varargs.h>
  404. #endif
  405.  
  406. void
  407. #if __STDC__
  408. err (int ex, const char *fmt, ...)
  409. #else
  410. err(ex, fmt, va_alist)
  411.     int ex;
  412.     char *fmt;
  413.         va_dcl
  414. #endif
  415. {
  416.     va_list ap;
  417.  
  418. #if __STDC__
  419.     va_start(ap, fmt);
  420. #else
  421.     va_start(ap);
  422. #endif
  423. #if 0
  424. fprintf(stderr, "cat - err\n");
  425. fflush(stderr);
  426. #endif
  427.     (void)fprintf(stderr, "cat: ");
  428.     (void)vfprintf(stderr, fmt, ap);
  429.     va_end(ap);
  430.     (void)fprintf(stderr, "\n");
  431.     if (ex) {
  432. #if WIN_NT
  433.         if (ppid == (pid_t) 1 && globulation == 0)
  434.             deglobulate();
  435. #endif
  436.         exit(EXIT_FAILURE);
  437.     }
  438.     rval = 1;
  439. }
  440.